/**
 * 
 */
package com.sysmanage.etl.controls;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;

import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.sysmanage.etl.model.ETL_Column;
import com.sysmanage.etl.model.ETL_DataSource;
import com.sysmanage.etl.model.ETL_Excel;
import com.sysmanage.etl.model.ETL_Property;
import com.sysmanage.etl.model.ETL_Property_Column;
import com.sysmanage.etl.model.ETL_Rule;
import com.sysmanage.etl.model.ETL_Table;
import com.sysmanage.etl.service.IColumnService;
import com.sysmanage.etl.service.IDataSourceService;
import com.sysmanage.etl.service.IExcelService;
import com.sysmanage.etl.service.IImportDataService;
import com.sysmanage.etl.service.IPropertyService;
import com.sysmanage.etl.service.IRuleService;
import com.sysmanage.etl.service.ITableService;
import com.sysmanage.etl.vo.ColumnVO;
import com.sysmanage.etl.vo.DataSourceVO;
import com.sysmanage.etl.vo.MappedVO;
import com.sysmanage.etl.vo.PropertyRuleVO;
import com.sysmanage.etl.vo.PropertyVO;
import com.sysmanage.etl.vo.TableVO;

/**
 * @author Yu Jou 2014年7月14日
 */
@Scope("prototype")
@Controller(value = "mappingTg")
public class MappingTg extends BaseETLTg {

	private static final long serialVersionUID = 2716916634873048079L;

	@Resource
	private IDataSourceService dataSourceService;
	@Resource
	private ITableService tableService;
	@Resource
	private IPropertyService propertyService;
	@Resource
	private IColumnService columnService;
	@Resource
	private IRuleService ruleService;
	@Resource
	private IImportDataService importDataService;
	@Resource
	private IExcelService excelService;
	// 数据源ID
	private Integer dataSourceId;
	// 表ID
	private Integer tableId;
	
	private Integer shopId;

	// excel id
	private Integer excelId;

	private Integer ruleIndex;

	private Integer ruleId;

	// 所有的数据源
	private List<DataSourceVO> dataSourceList = new ArrayList<DataSourceVO>(0);
	// 所有的Table
	private List<TableVO> tableList = new ArrayList<TableVO>(0);
	// 所有的Table属性
	private List<PropertyVO> propList = new ArrayList<PropertyVO>(0);
	// 所有的Excel列
	private List<ColumnVO> columnList = new ArrayList<ColumnVO>(0);

	private Map<String, Object> result = new HashMap<String, Object>();

	private String mapped;

	public String main() {
		return "main";
	}
	
	
	public String index() {
		return "index";
	}

	public String mapping() {
		return "mapping";
	}

	public String rule() {
		return "rule";
	}

	public void prepareRule() {
		this.prepareColumn();
		this.prepareProperty();
	}

	// 返回DataSource JSON 数据
	public String dataSource() {
		return "dataSourceJSON";
	}

	public void prepareDataSource() {

		Collection<ETL_DataSource> list = this.dataSourceService.findList("from ETL_DataSource");

		for (ETL_DataSource dataSource : list) {
			DataSourceVO vo = new DataSourceVO();
			BeanUtils.copyProperties(dataSource, vo);
			this.dataSourceList.add(vo);
		}
	}

	// 返回Table JSON 数据
	public String table() {
		return "tableJSON";
	}

	public void prepareTable() {
		List<ETL_Table> list = this.tableService.findList("from ETL_Table where dataSource.dataSource_id = " + dataSourceId + " and display = " + true);
		for (ETL_Table table : list) {
			TableVO vo = new TableVO();
			BeanUtils.copyProperties(table, vo);
			if (vo.getTable_alais() != null) {
				vo.setTable_name(vo.getTable_alais() + "(" + vo.getTable_name() + ")");
			}
			this.tableList.add(vo);
		}
	}
	
	// 返回Table JSON 数据
	public String property() {
		return "propertyJSON";
	}

	public void prepareProperty() {
		List<ETL_Property> list = this.propertyService.findList("from ETL_Property where table.table_id = " + tableId + " order by property_id asc");
		for (ETL_Property table : list) {
			PropertyVO vo = new PropertyVO();
			BeanUtils.copyProperties(table, vo);
			if (vo.getProperty_alias() != null) {
				vo.setProperty_name(vo.getProperty_alias() + "(" + vo.getProperty_name() + ")");
			}
			this.propList.add(vo);
		}
	}

	// 返回 Column JSON数据
	public String column() {
		return "columnJSON";
	}

	public void prepareColumn() {
		List<ETL_Column> list = this.columnService.findList("from ETL_Column where shop_id = " + this.getShopId() + " order by column_cellIndex asc");
		
		for (ETL_Column columm : list) {
			ColumnVO vo = new ColumnVO();
			BeanUtils.copyProperties(columm, vo);
			this.columnList.add(vo);
		}
	}

	// 返回Table JSON 数据
	@SuppressWarnings({ "deprecation", "unchecked" })
	public String save() {
		JSONArray ja = JSONArray.fromObject(mapped);
		List<MappedVO> list = JSONArray.toList(ja, MappedVO.class);
		Integer rule_id = ruleService.save(list);
		result.put("message", "操作成功!");
		result.put("success", true);
		result.put("rule_id", rule_id);
		return "updateJSON";
	}

	public String show() {
		return "list";
	}

	public void excute() {
		String feedback = null;
		try {
			ETL_Excel etlExcel = excelService.findById(excelId);
			
			int total = ruleService.findCountBySql("from ETL_Rule r where r.shop_id = " + shopId);
			
			if (total > 0) {
				feedback = importDataService.saveData(etlExcel);
			} else {
				feedback = "改分公司还未配置导入规则，不能执行导入操作";
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			this.outJsonPlainString(response, "{\"msg\":" + e.getMessage() + "}");
		}
		this.outJsonPlainString(response, "{\"msg\":\"" + feedback + "\"}");
	}
	
	
	public void removeRule() {
		ETL_Rule rule = ruleService.findById(ruleId);
		if (rule != null) {
			ruleService.deleteRule(rule);
		}
		this.outJsonPlainString(response, "{\"success\":true}");
	}
	

	public void rules() {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setIgnoreDefaultExcludes(false);
		jsonConfig.setExcludes(new String[] { "propertys", "rule", "dataSource", "specialValues" });
		List<ETL_Rule> rules = ruleService.findList("from ETL_Rule r where r.shop_id = " + this.getShopId() + " order by r.rule_index asc");
		JSONArray jsonArray = JSONArray.fromObject(rules, jsonConfig);
		this.outJsonString(response, jsonArray.toString());
	}

	public void propertyRules() {
		List<PropertyRuleVO> vos = new ArrayList<PropertyRuleVO>();
		
		List<ETL_Rule> rules = ruleService.findList("from ETL_Rule r where r.shop_id = " + this.getShopId() + " order by r.rule_index asc");

		ETL_Rule rule = null;
		for (ETL_Rule item : rules) {
			if (item.getRule_id().equals(ruleId)) {
				rule = item;
				break;
			}
		}
		int ruleIndex = 0;
		int ruleType = -1;
		ETL_Property returnProp = null;
		if (rule == null) {
			List<ETL_Property> list = propertyService.findList("from ETL_Property p where p.table.table_id = " + tableId + " order by p.property_id asc");
			for (ETL_Property property : list) {
				PropertyRuleVO vo = new PropertyRuleVO();
				vo.setPid(property.getProperty_id());
				if (property.getProperty_alias() != null) {
					vo.setPname(property.getProperty_name() + " (" + property.getProperty_alias() + ")");
				} else {
					vo.setPname(property.getProperty_name());
				}
				vo.setIsForeignKey(property.getProperty_isForeignKey());
				vo.setIsPrimaryKey(property.getProperty_isPrimaryKey());
				vo.setIsRepeat(property.getProperty_isRepeat());
				vos.add(vo);
			}
		} else {
			ruleIndex = rule.getRule_index();
			ruleId = rule.getRule_id();
			ruleType = rule.getRule_type();
			returnProp = rule.getRule_return_property();
			for (ETL_Property_Column pc : rule.getPropertyColumns()) {
				PropertyRuleVO vo = new PropertyRuleVO();
				ETL_Property property = pc.getProperty();
				vo.setPid(property.getProperty_id());
				if (property.getProperty_alias() != null) {
					vo.setPname(property.getProperty_name() + " (" + property.getProperty_alias() + ")");
				} else {
					vo.setPname(property.getProperty_name());
				}
				vo.setIsForeignKey(pc.getIsForeignKey());
				vo.setIsPrimaryKey(pc.getIsPrimaryKey());
				vo.setIsRepeat(pc.getIsRepeat());
				vo.setCid(pc.getColumn() == null ? null : pc.getColumn().getColumn_id());
				vo.setIndex(pc.getPc_index());
				vo.setPrimary(pc.getPrimaryKey());
				vo.setOtherValue(pc.getOtherValue());
				vos.add(vo);
			}
		}
		JSONArray jsonArray = JSONArray.fromObject(vos);
		if(returnProp != null){
			this.outJsonPlainString(response, "{\"rows\":" + jsonArray.toString() + ",\"ruleIndex\":" + ruleIndex + ",\"ruleId\":" + ruleId + ",\"ruleType\":" + ruleType + ",\"returnProp\":" + returnProp.getProperty_id() + "}");
		}else{
			this.outJsonPlainString(response, "{\"rows\":" + jsonArray.toString() + ",\"ruleIndex\":" + ruleIndex + ",\"ruleId\":" + ruleId + ",\"ruleType\":" + ruleType + "}");
		}
		
	}

	public List<DataSourceVO> getDataSourceList() {
		return dataSourceList;
	}

	public List<TableVO> getTableList() {
		return tableList;
	}

	public List<ColumnVO> getColumnList() {
		return columnList;
	}

	public void setDataSourceId(Integer dataSourceId) {
		this.dataSourceId = dataSourceId;
	}

	public List<PropertyVO> getPropList() {
		return propList;
	}

	public void setTableId(Integer tableId) {
		this.tableId = tableId;
	}

	public void setMapped(String mapped) {
		this.mapped = mapped;
	}

	public void setExcelId(Integer excelId) {
		this.excelId = excelId;
	}

	public Integer getExcelId() {
		return excelId;
	}

	public Integer getTableId() {
		return tableId;
	}

	public Integer getRuleIndex() {
		return ruleIndex;
	}

	public Map<String, Object> getResult() {
		return result;
	}

	public void setRuleId(Integer ruleId) {
		this.ruleId = ruleId;
	}

	public Integer getRuleId() {
		return ruleId;
	}


	public Integer getShopId() {
		return shopId;
	}


	public void setShopId(Integer shopId) {
		this.shopId = shopId;
	}

}
